package com.chm.iteration;

import java.util.Scanner;

/**
 * author:Cheng Huiming
 * date:2017.12.29
 * description:Demand：Calculate the root of the quadratic equation by Newton iteration.
 */
public class NewtonIterator {
    /**
     * The entry point of application.
     *
     * @param args the input arguments
     */
    public static void main(String[] args) {

        //Create a Scanner
        Scanner input = new Scanner(System.in);
        //Promt the user enter three double
        System.out.println("Enter iteration times:");
        int count = input.nextInt();
        System.out.println("Enter precision:");
        double precision = input.nextDouble();
        System.out.println("Enter initial value double:");
        double X = input.nextDouble();

        // Calling function
        double result = newtonMethod(X, count, precision);
        //Get result
        if (result == 1) {
            System.out.printf("方程a*x*x+b*x+c=0\n在" + X + ":%f\n", X);
        } else {
            System.out.print("迭代失败!\n");
        }
    }
    //Quadratic equation

    /**
     * Quadratic equation double.
     *
     * @param x Initial value
     * @param a Quadratic Coefficients
     * @param b Monomial coefficient
     * @param c Constant double
     * @return 1 :reach precision;0:Do not reach precision
     */
    private static double quadraticEquation(double x, double a, double b, double c) {
        return a * x * x + b * x + c;
    }

    /**
     * Derived function double.
     *
     * @param x the x
     * @param a the a
     * @param b the b
     * @return the double
     */
//Derivative
    static double derivedFunction(double x, double a, double b) {
        return 2 * a * x + b;
    }

    /**
     * Newtonlterator method
     *
     * @param H         the h 为什么要用 H，啥意思，参数名称怎么写的
     * @param count     the count
     * @param precision the precision
     * @return the int
     */
    private static int newtonMethod(double H, int count, double precision) {
        Scanner input = new Scanner(System.in);
        System.out.println("Enter Quadratic Coefficients:");
        double a = input.nextDouble();
        System.out.println("Enter Monomial coefficient double:");
        double b = input.nextDouble();
        System.out.println("Enter constant double:");
        double c = input.nextDouble();
        //Define three variable
        double x0, x1;
        int i = 0;
        // The initial value of the iteration
        x0 = H;
        // The number of cycles does not exceed the maximum number of settings
        while (i < count) {
            //If initial value is ok,return 0
            if (derivedFunction(x0, a, b) == 0.0) {
                System.out.print("迭代过程中导数为0!\n");
                return 0;
            }
            //Newton iterative calculation
            x1 = x0 - quadraticEquation(x0, a, b, c) / derivedFunction(x0, a, b);
            //The default end condition
            if (Math.abs(x1 - x0) < precision || Math.abs(quadraticEquation(x1, a, b, c)) < precision) {
                //return result
                H = x1;
                return 1;
            }
            //Do not reach end condition
            else {
                //Next iterative
                x0 = x1;
            }
            //The number of iterations is cumulative
            i++;
        }
        System.out.print("迭代次数超过预设值!仍没有达到精度！\n");
        return 0;
    }
}
